/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.neuralstudio.utils;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import org.jane.core.networks.AbstractSupervisedNeuralNetwork;
import org.math.plot.Plot2DPanel;
import org.math.plot.Plot3DPanel;
import org.math.plot.PlotPanel;

/**
 *
 * @author william
 */
public class AproximationTrainerThread extends Thread{
    private AbstractSupervisedNeuralNetwork net;
    private int iterations;
    private List<List<List<Float>>> dataset;
    private PlotPanel plotPanel;
    private double[] x;
    private double[] y;
    private double[][] z;
    private double[][] xy;
    private final JProgressBar bar;
    private final Plot2DPanel errorPlot;
    private double[] iter;
    private double[] errors;
    private final Float minError;
    private final boolean dots;
    private int index;
    private final JButton button;
    private Float batchError;
    private final JTextArea infoTextArea;

    public AproximationTrainerThread(List<List<List<Float>>> dataset,PlotPanel plotPanel, AbstractSupervisedNeuralNetwork net, int iterations,
            Float minError,JProgressBar bar,Plot2DPanel errorPlot, boolean dots,JButton button,JTextArea infoTextArea) {
        this.dataset = dataset;
        this.net = net;
        this.iterations = iterations;
        this.plotPanel = plotPanel;
        this.bar = bar;
        this.errorPlot = errorPlot;
        this.minError = minError;
        this.dots = dots;
        this.button = button;
        this.infoTextArea = infoTextArea;
    }
    class MyRunnable implements Runnable {

        public void run() {
            //bar.setIndeterminate(false);
            if (dataset.get(0).get(0).size() == 1) {
                
                if (plotPanel instanceof Plot2DPanel) {
                    //if (!dots) {
                    //    ((Plot2DPanel)plotPanel).addLinePlot("Respuesta red",Color.blue, x, y);
                    //}else{
                        ((Plot2DPanel)plotPanel).addLinePlot("Respuesta red",Color.blue, xy);
                    //}
                }
                if (plotPanel instanceof Plot3DPanel) {
                    ((Plot3DPanel)plotPanel).addGridPlot("Respuesta red", Color.blue, x, y, z);
                }

                ((JPanel)plotPanel.getParent()).revalidate();
                plotPanel.getParent().repaint();
            }
            button.setEnabled(true);
            errorPlot.addLinePlot("Error",Color.red,iter,errors);
            ((JPanel)errorPlot.getParent()).revalidate();
            errorPlot.getParent().repaint();
            infoTextArea.append(System.getProperty("line.separator"));
            infoTextArea.append("Suma de cuadrados residuales: "+batchError);
            infoTextArea.append(System.getProperty("line.separator"));
        }

    }

    public void run() {
        //List<List<List<Float>>> resultData = new ArrayList<List<List<Float>>>();
        //bar.setmin
        iter = new double[iterations];
        errors = new double[iterations];
        index = 0;
        try {
             do{
                errors[index] = net.train(dataset).get(0);
                iter[index] = index;
                index++;

                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        bar.setValue(index);
                    }
                });
            }while (index < iterations);
        }catch(IndexOutOfBoundsException e) {

        }
        this.batchError = net.getBatchError();
        if (dataset.get(0).get(0).size() == 1) {
            updatePlots();
            
        }
        SwingUtilities.invokeLater(new MyRunnable());

    }
    public void updatePlots() {
        x = new double[dataset.size()];
        y = new double[dataset.size()];
        xy = new double[dataset.size()][2];
        z = new double[x.length][x.length];
        int i = 0;
        for (List<List<Float>> dataElement : dataset) {
           // if (dots) {
                xy[i][0] = dataElement.get(0).get(0);
                xy[i][1] = net.processData(dataElement.get(0)).get(0);
            //}
            /*
            x[i] = dataElement.get(0).get(0);
            if (plotPanel instanceof Plot3DPanel){
                y[i] = dataElement.get(0).get(1);
            }
            if (plotPanel instanceof Plot2DPanel) {
                y[i] = net.processData(dataElement.get(0)).get(0);
            }
             *
             */
            i++;
        }
        if (plotPanel instanceof Plot3DPanel) {
            for (int j = 0; j < x.length; j++) {
                for (int k = 0; k < y.length; k++) {
                    List<Float> temp = new ArrayList<Float>();
                    temp.add((float)y[k]);
                    temp.add((float)y[j]);
                    z[k][j] = (double)net.processData(temp).get(0);
                }
            }
        }
        
    }

}

